/*
 * @Author: 肖燕 2461435122@qq.com
 * @Date: 2023-09-18 10:08:31
 * @LastEditors: 肖燕 2461435122@qq.com
 * @LastEditTime: 2023-09-27 14:33:00
 * @FilePath: /mris-platform-all/src/assets/scripts/tools/axios-canceler.js
 * @Description: 取消axios请求
 */
import { cloneDeep } from 'lodash'
// 用于存储每个请求的标识和取消函数
const pendingMap = new Map()

/**
 * @description: 只要是请求地址、请求方式、请求参数一样，那么我们就能认为是一样的
 * @param {*} config
 * @return {*}
 */
const getPendingUrl = (config) => {
  const { url, method, params } = config
  let data = config.data
  // response里面返回的config.data是个字符串对象
  if (typeof data === 'string') {
    // data = JSON.parse(data)
  } else {
    data = cloneDeep(data)
    if (!data.isRepeatRequest) {
      delete data.timestamp
    }
  }
  return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&')
}

export class AxiosCanceler {
  /**
   * 添加请求
   * @param config 请求配置
   */
  addPending (config) {
    this.removePending(config)
    const url = getPendingUrl(config)
    const controller = new AbortController()
    config.signal = controller.signal
    if (!pendingMap.has(url)) {
      // 如果当前请求不在等待中，将其添加到等待中
      pendingMap.set(url, controller)
    }
  }

  /**
   * 清除所有等待中的请求
   */
  removeAllPending () {
    pendingMap.forEach((abortController) => {
      if (abortController) {
        abortController.abort()
      }
    })
    this.reset()
  }

  /**
   * 移除请求
   * @param config 请求配置
   */
  removePending (config) {
    const url = getPendingUrl(config)
    if (pendingMap.has(url)) {
      // 如果当前请求在等待中，取消它并将其从等待中移除
      const abortController = pendingMap.get(url)
      if (abortController) {
        abortController.abort(url)
      }
      pendingMap.delete(url)
    }
  }

  /**
   * 重置
   */
  reset () {
    pendingMap.clear()
  }
}
